package purchaseOrder

import (
	"context"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"github.com/kuangshp/go-utils/k"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
	"insighttracking/apps/admin/auth"
	"insighttracking/common/utils"
	"insighttracking/query/dao"
	"insighttracking/query/model"
	"insighttracking/query/service"
	"net/http"

	"insighttracking/apps/admin/internal/svc"
	"insighttracking/apps/admin/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
	"os"
)

type CreatePurchaseOrderApiLogic struct {
	logx.Logger
	ctx     context.Context
	svcCtx  *svc.ServiceContext
	Request *http.Request
}

func NewCreatePurchaseOrderApiLogic(ctx context.Context, svcCtx *svc.ServiceContext, request *http.Request) *CreatePurchaseOrderApiLogic {
	hostname, _ := os.Hostname()
	return &CreatePurchaseOrderApiLogic{
		Logger: logx.WithContext(ctx).WithCallerSkip(0).WithFields(
			logx.Field("Log_UUID", uuid.New().String()),
			logx.Field("hostname", hostname)),
		ctx:     ctx,
		svcCtx:  svcCtx,
		Request: request,
	}
}

func (l *CreatePurchaseOrderApiLogic) CreatePurchaseOrderApi(req *types.CreatePurchaseOrdersReq) (resp string, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return "", err
	}
	// 计算总价
	var purchaserTotalCount = decimal.Zero
	var purchaserTotalAmount = decimal.Zero
	for _, item := range req.SpuList {
		purchaserCount, _ := decimal.NewFromString(item.PurchaserCount)
		purchaserPrice, _ := decimal.NewFromString(item.PurchaserPrice)
		purchaserAmount, _ := decimal.NewFromString(item.PurchaserAmount)
		if !purchaserCount.Mul(purchaserPrice).Equal(purchaserAmount) {
			return "", errors.New("商品行价格计算错误")
		}
		purchaserTotalCount = purchaserTotalCount.Add(purchaserCount)
		purchaserTotalAmount = purchaserTotalAmount.Add(purchaserCount.Mul(purchaserPrice))
	}
	// 1.创建订单
	tx := dao.Use(l.svcCtx.MysqlDb).Begin()
	var purchaseOrderData = &model.PurchaseOrdersEntity{
		OrderNo:              utils.GenerateTodayOrderNo(l.svcCtx.RedisDb, "CGD"),
		EnterpriseID:         accountInfo.EnterpriseId,                          // 关联到enterprise表主键id
		SupplierID:           req.SupplierID,                                    // 供应商,关联到supplier表主键id
		PurchaserID:          req.PurchaserID,                                   // 采购员,关联到
		ExpectationGoodsDate: utils.DateTimeStrToTime(req.ExpectationGoodsDate), // 期望收货日期
		PurchaserTotalCount:  purchaserTotalCount,                               // 采购总数量
		PurchaserTotalAmount: purchaserTotalAmount,                              // 采购总金额
		Source:               1,                                                 // 来源,0表示采购计划生成,1表示手动创建采购单
		Types:                req.Types,                                         // 类型,0表示供应商创建,1表示现场采购
		Remark:               req.Remark,                                        // 备注
		OperateID:            accountInfo.PersonId,                              // 操作人,关联到person表主键id
		OperateName:          accountInfo.PersonName,                            // 操作人名称
	}
	if err = service.PurchaseOrderService.CreateApi(l.ctx, tx, purchaseOrderData); err != nil {
		if err = tx.Rollback(); err != nil {
			return "", err
		}
		return "", errors.New("创建订单失败")
	}
	spuIdList := k.Map(req.SpuList, func(item types.CreatePurchaseOrdersDetailReq, index int) int64 {
		return item.SpuID
	})
	spuEntities, err := service.SpuService.GetSpuByIdListApi(l.ctx, spuIdList)
	var spuMap = make(map[int64]*model.SpuEntity)
	if err == nil && len(spuEntities) > 0 {
		spuMap = k.ToMap(spuEntities, func(item *model.SpuEntity) (int64, *model.SpuEntity) {
			return item.ID, item
		})
	} else {
		if err = tx.Rollback(); err != nil {
			return "", errors.New("创建失败")
		}
		return "", errors.New("传递的商品id错误")
	}
	unitIdList := k.Map(spuEntities, func(item *model.SpuEntity, index int) int64 {
		return item.UnitID
	})
	unitEntities, err := service.UnitService.GetByIdListApi(l.ctx, unitIdList)
	var unitMap = make(map[int64]string)
	if err == nil && len(unitEntities) > 0 {
		unitMap = k.ToMap(unitEntities, func(item *model.UnitEntity) (int64, string) {
			return item.ID, item.Name
		})
	}
	spuUnitMap := k.ToMap(spuEntities, func(item *model.SpuEntity) (int64, int64) {
		return item.ID, item.UnitID
	})
	fmt.Println(k.MapToString(unitMap), "单位map")
	// 创建订单详情
	var purchaseOrderDetail = make([]*model.PurchaseOrdersDetailEntity, 0)
	for _, item := range req.SpuList {
		var spuEntity, isOk = spuMap[item.SpuID]
		if !isOk {
			continue
		}
		purchaserPrice, _ := decimal.NewFromString(item.PurchaserPrice)
		purchaserCount, _ := decimal.NewFromString(item.PurchaserCount)
		purchaserAmount, _ := decimal.NewFromString(item.PurchaserAmount)
		fmt.Println(unitMap[item.SpuID], "单位", item.SpuID)
		purchaseOrderDetail = append(purchaseOrderDetail, &model.PurchaseOrdersDetailEntity{
			PurchasePlanID:          0,                               // 采购计划表purchase_plan主键id,如果pc创建的采购单这里为空
			PurchaseOrdersID:        purchaseOrderData.ID,            // 采购单purchase_orders表主键id
			SpuID:                   item.SpuID,                      // 商品,关联到spu表主键id
			SnapshotSpuName:         spuEntity.Name,                  // '快照商品名称
			SnapshotProductImageURL: spuEntity.ProductImageURL,       // 快照产品图片
			SnapshotSpuType:         spuEntity.SpuType,               // 快照商品类型,0表示基础商品,1表示加工商品
			SnapshotUnit:            unitMap[spuUnitMap[item.SpuID]], // 快照单位
			SnapshotCategoryID:      spuEntity.CategoryID,            // 快照分类id
			SnapshotCategory:        spuEntity.CategoryName,          // 快照分类
			SnapshotPrice:           spuEntity.SalesPrice,            // 快照商品单价
			LossRate:                spuEntity.LossRate,              // 快照损耗率
			PurchaserPrice:          purchaserPrice,                  // 采购单价
			PurchaserCount:          purchaserCount,                  // 采购数量
			PurchaserAmount:         purchaserAmount,                 // 采购金额
			Remark:                  item.Remark,                     // 备注
		})
	}
	if err = service.PurchaseOrderDetailService.CreateBatchApi(l.ctx, tx, purchaseOrderDetail); err != nil {
		if err1 := tx.Rollback(); err1 != nil {
			return "", errors.New("创建失败")
		}
		return "", errors.New("创建失败")
	}
	fmt.Println("--------------------采购入库单-------------------------------")
	// 创建采购入库单
	warehouseEntity, err := service.WarehouseService.GetWarehouseByEnterpriseDefaultIdApi(l.ctx, accountInfo.EnterpriseId)
	if errors.Is(err, gorm.ErrRecordNotFound) {
		if err1 := tx.Rollback(); err1 != nil {
			return "", errors.New("创建失败")
		}
		return "", errors.New("请先设置默认仓库")
	}
	purchaseStoreEntity := model.PurchaseStoreEntity{
		EnterpriseID:     accountInfo.EnterpriseId,                             // 关联到enterprise表主键id
		PurchaseOrdersID: purchaseOrderData.ID,                                 // 采购单purchase_orders表主键id,如果是pc创建的时候为0
		OrderNo:          utils.GenerateTodayOrderNo(l.svcCtx.RedisDb, "CGRK"), // 操作流水号
		SupplierID:       req.SupplierID,                                       // 供应商,关联到supplier表主键id
		PurchaserID:      req.PurchaserID,                                      // 采购员,关联到
		WarehouseID:      warehouseEntity.ID,                                   // 入库仓,关联到warehouse表主键id
		TotalCount:       purchaseOrderData.PurchaserTotalCount,                // 采购总重量
		Types:            req.Types,                                            // 类型,0表示供应商创建,1表示现场采购
		Status:           0,                                                    // 状态,0表示待入库,10表示部分收货,20表示全部收货
		CreatedID:        accountInfo.PersonId,                                 // 创建人
		CreatedName:      accountInfo.PersonName,                               // 创建人
	}
	if err = service.PurchaseStoreService.CreatePurchaseStoreApi(l.ctx, tx, &purchaseStoreEntity); err != nil {
		if err1 := tx.Rollback(); err1 != nil {
			return "", errors.New("创建失败")
		}
		return "", errors.New("创建失败")
	}
	// 创建采购入库单详情
	var purchaseStoreDetailEntity = make([]*model.PurchaseStoreDetailEntity, 0)
	for _, item := range purchaseOrderDetail {
		purchaseStoreDetailEntity = append(purchaseStoreDetailEntity, &model.PurchaseStoreDetailEntity{
			PurchaseOrdersDetailID:  item.ID,                      // 采购单详情表主键purchase_orders_detail表主键id
			PurchaseStoreID:         purchaseStoreEntity.ID,       // 采购入库单purchase_store表主键id
			SpuID:                   item.SpuID,                   // 商品,关联到spu表主键id
			SnapshotSpuName:         item.SnapshotSpuName,         // 快照商品名称
			SnapshotProductImageURL: item.SnapshotProductImageURL, // 快照产品图片
			SnapshotSpuType:         item.SnapshotSpuType,         // 快照商品类型,0表示基础商品,1表示加工商品
			SnapshotUnit:            item.SnapshotUnit,            // 快照单位
			SnapshotCategoryID:      item.SnapshotCategoryID,      // 快照分类id
			SnapshotCategory:        item.SnapshotCategory,        // 快照分类
			SnapshotPrice:           item.SnapshotPrice,           // 快照商品单价
			LossRate:                item.LossRate,                // 快照损耗率
			PurchaserPrice:          item.PurchaserPrice,          // 采购单价
			PurchaserCount:          item.PurchaserCount,          // 采购重量
			PurchaserAmount:         item.PurchaserAmount,         // 采购金额
		})
	}
	if err = service.PurchaseStoreDetailService.CreateBatchApi(l.ctx, tx, purchaseStoreDetailEntity); err != nil {
		if err1 := tx.Rollback(); err1 != nil {
			return "", errors.New("创建失败")
		}
		return "", errors.New("创建失败")
	}
	if err = tx.Commit(); err != nil {
		return "", errors.New("创建失败")
	}
	return "操作成功", nil
}
